package nl.cypherpunk.statefuzzer.smtp;

import nl.cypherpunk.statefuzzer.tls.TLSTestService;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;

public class Replay {
    public static void main(String[] args) throws Exception {

        if (args.length >= 3) {
            SMTPTestService smtp = new SMTPTestService();
            //tls.setOutput(true);
            smtp.setOutputDir(args[0]);
            smtp.setTarget(args[4]);
            smtp.setHost("127.0.0.1");
            smtp.setPort(Integer.valueOf(args[1]));
            smtp.setCommand(args[3]);
            smtp.setReceiveMessagesTimeout(800);
            //smtp.setConsoleOutput(false);
            smtp.setRestartTarget(false);
            smtp.start();
            //int step =  Integer.parseInt(args[7]);
            File file = new File(args[2]);
            File[] tempList = file.listFiles();
            List fileList = Arrays.asList(tempList);
            Collections.sort(fileList, new Comparator<File>() {
                @Override
                public int compare(File o1, File o2) {
                    if (o1.isDirectory() && o2.isFile())
                        return -1;
                    if (o1.isFile() && o2.isDirectory())
                        return 1;
                    return o1.getName().compareTo(o2.getName());
                }
            });

            int totalNum = 0;
            for (File file1 : tempList) {
                File temp = new File(file1.getPath());
                System.out.println(file1.getName());
                totalNum++;
                try {
                    InputStream fileIn = new FileInputStream(temp);
                    //DataInputStream in = new DataInputStream(fileIn);

                    // 使用缓存区读入对象效率更快
                    BufferedInputStream in = new BufferedInputStream(fileIn);
                    byte[] len = new byte[1024];
                    int length;
                    List<byte[]> seed = new ArrayList<>();
                    smtp.reset();
                    while (in.read(len, 0, 4) != -1) {
                        length = byteArrayToInt(len);
                        byte[] bys = new byte[length];
                        in.read(bys, 0, length);
                        try {
                            String output = smtp.sendFuzzingMessage(bys);
                            if (output.contains("Closed"))
                                break;
                        } catch (Exception e) {
                            System.out.println(e);
                        }
                        seed.add(bys);
                    }
                    in.close();
                    fileIn.close();
                    smtp.closeSocket();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                int coverage = smtp.getCoverage();
                System.out.println(coverage);
            }
            smtp.closeSocket();
            smtp.close();
            return;
        }


    }
    public static int byteArrayToInt(byte[] bytes) {
        int value=0;
        for(int i = 0; i < 4; i++) {
            int shift= i * 8;
            value +=(bytes[i] & 0xFF) << shift;
        }
        return value;
    }
}
